iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0
Modern Web

web component - 次世代網頁技術的重要拼圖系列 第 4

[Day3] Custom element的建立和使用

  • 分享至 

  • xImage
  •  

前端三大框架小弟我除了Angular之外都算熟,之後的文章可能會帶入點React和Vue的部分,畢竟現在網頁工程師或多或少都碰過三大框架之一。

建構custom element

custom element 主要由二部分組成,第一部分是利用JS建立一個可以生成custom element的constructor,另一部分是使用web API把constructor註冊到window。

JS的部分

constructor通常都是使用Class來extend HTMLElement的方式來建構,這部分就像是react 的 class component。

constructor可以使用Prototype來建構,但討厭class語法如小弟我,也不建議用class以外的方式來建構。

      /* 簡單寫法 */
    class MyElement extends HTMLElement { // 必要
        constructor() { // constructor非必要,但建議加入
            super();
        }

        connectedCallback() { // 必要,大部分程式碼都請寫在這裡
            // 通常是建議使用shadow DOM,而不是直接寫入this,等到介紹Shadow時再說明
            this.innerHTML= `<div>Hallo World!</div>` 
        }
    }
      /* 參考react class conponent後的,我常用的寫法 */
    class MyElement extends HTMLElement {
        constructor() {
            super();
            this.render = this.render.bind(this);
        }

        connectedCallback() {
            this.innerHTML= this.render()
        }
        render() {
            return <div>Hallo World!</div>
        }
    }
    /*  react class component的對應寫法 */
    class MyElement extends React.Component {
      constructor(props) {
        super(props);
      }
      render() {
        return <div>Hallo World!</div>
      }
    }

Web API的部分

Web API的部分就簡單多了,使用customElements這個全域物件內的define方法就能把前一部分的constructor註冊到window上了。但有一個限制,註冊的名稱中至少要有一個'-'

customElements.define('my-element', MyElement); 
// 正確的用法
customElements.define('my-element-first', MyElement);
// 正確的用法,至少有使用到一個"-"
customElements.define('myelement', MyElement);
// 錯誤的用法,沒有使用到'-'

HTML的部分

HTML中使用就簡單多了,直接當成普通的HTML元素來使用就可以了

<section>
    <!-- 正常的用法 -->
    <my-element></my-element> 
</section>
<section>
    <!-- 正常的用法,但也許有些瀏覽器會報錯 -->
    <my-element />
</section>
<section>
    <!-- 不管是<my-element></my-element>或 <my-element /> ,都會做出下面的樣子-->
    <div>Hallo World!</div>
</section>

例子

帶我進入軟體業的前輩曾經這樣說,一個Todo-list的網頁是最適合用來練習前後端的系統了。本系列的本章都會以todolist當例子

HTML的部分

<!-- 對照組 -->
<section id="target" class="todolist">
    <article class="todo-item">
        <input type="checkbox" name="check" />
        <h1 class="item-title">今天晚上公司聚餐</h1>
        <div class="item-tags">
            <span class="item-tag">吃飯</span>
            <span class="item-tag">公司</span>
        </div>
        <p class="item-descption">吃到飽餐廳吃飯</p>
    </article>
</section>
<!-- 傳統的Javascript用法 -->
<section id="tradition" class="todolist"></section>
<!-- 使用web component -->
<section id="web-component" class="todolist">
    <todo-item></todo-item>
</section>

Javascript的部分

/*  傳統的Javascript用法 */
function todoItemJS ({parentNode}) {
    const rootArticle = document.createElement('article');
    rootArticle.classList.add('todo-item');
    rootArticle.innerHTML= `
        <input type="checkbox" name="check" />
        <h1 class='item-title'>今天晚上公司聚餐</h1>
        <div class='item-tags'>
            <span class=='item-tag'>吃飯</span>
            <span class=='item-tag'>公司</span>
        </div>
        <p class='item-descption'>吃到飽餐廳吃飯</p>
    `
    parentNode.appendChild(rootArticle);
}
const parentNode = document.getElementById('tradition');
todoItemJS({parentNode})

/*  web component */
class TodoItem extends HTMLElement {
    constructor() {
        super();
        this.render = this.render.bind(this);
    }

    connectedCallback() {
        this.innerHTML= this.render()
    }
    render() {
        // render the element
        const rootArticle = document.createElement('article');
        rootArticle.classList.add('todo-item');
        rootArticle.innerHTML= `
            <input type="checkbox" name="check" />
            <h1 class='item-title'>今天晚上公司聚餐</h1>
            <div class='item-tags'>
                <span class=='item-tag'>吃飯</span>
                <span class=='item-tag'>公司</span>
            </div>
            <p class='item-descption'>吃到飽餐廳吃飯</p>
        `
        return rootArticle;
    }
}
customElements.define('todo-item', TodoItem);


上一篇
[Day2] Web component 解決和沒解決的問題
下一篇
[Day4] Custom element - 像HTML Element一樣使用
系列文
web component - 次世代網頁技術的重要拼圖30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言